﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using devtm.Editor.Configuration.formWpf;
using System.IO;
using System.Reflection;
using System.Collections;
using devtm.Helpers;
using System.Diagnostics;
using devtm.Configuration;

namespace devtm.Editor.Configuration
{
    public static class ActionsHelper
    {

        public static void AddItemToSectionConnectionString(ElementSection elementSection)
        {

            // calcule la clef
            string key = "newconn" + (elementSection.ConfigurationElement as ConnectionStringSettingsCollection)
                .Count.ToString();
            // create
            var con = new ConnectionStringSettings(key, "Integrated Security=True");

            
            
            (elementSection.ConfigurationElement as ConnectionStringSettingsCollection).Add(con);


            var section = elementSection.AddItemFromCollection(key, 10, con);


            MethodInfo MethodRedo = AccessPrivatePropertyHelper.GetMethod(elementSection.ConfigurationElement, "Add").First();
            MethodInfo MethodUndo = AccessPrivatePropertyHelper.GetMethod(elementSection.ConfigurationElement, "Remove")
                .Where(new  { settings = typeof(ConnectionStringSettings)}).First();
            Command.CommandHelpers.HasAddedItemToList(section, elementSection.ConfigurationElement, MethodRedo, MethodUndo, con, Command.TypeChange.Add);

            
        }

        public static void RemoveConnectionString(IElementSection i, IElementSection parent)
        {

            MethodInfo MethodUndo = AccessPrivatePropertyHelper.GetMethod(parent.ConfigurationElement, "Add").First();
            MethodInfo MethodRedo = AccessPrivatePropertyHelper.GetMethod(parent.ConfigurationElement, "Remove")
                .Where(new { settings = typeof(ConnectionStringSettings) }).First();

            Command.CommandHelpers.HasAddedItemToList(i, parent.ConfigurationElement, MethodRedo, MethodUndo, i.ConfigurationElement, Command.TypeChange.Remove);

            (parent.ConfigurationElement as ConnectionStringSettingsCollection)
         .Remove((i.ConfigurationElement as ConnectionStringSettings));
            (parent as ElementSection).Items.Remove(i);
        }

        public static void AddItemToSectionKeyValueCollection(ElementSection elementSection)
        {

            // calcule la clef
            string key = "key" + (elementSection.ConfigurationElement as KeyValueConfigurationCollection)
                .Count.ToString();

            // demande le choix de l'utilisateur.
            key = InputBox.ShowDialog(
                Properties.Resources.WriteTheKeyName
                , Properties.Resources.AddAItem
                , key
                , (c) => !(elementSection.ConfigurationElement as KeyValueConfigurationCollection).AllKeys.Contains(c)
                , Properties.Resources.ThisKeyAllreadyExists);

            if (string.IsNullOrEmpty(key))
                return;

            // create
            KeyValueConfigurationElement con = new KeyValueConfigurationElement(key, string.Empty);


            (elementSection.ConfigurationElement as KeyValueConfigurationCollection).Add(con);


            MethodInfo MethodRedo = AccessPrivatePropertyHelper.GetMethod(elementSection.ConfigurationElement, "Add").First();
            MethodInfo MethodUndo = AccessPrivatePropertyHelper.GetMethod(elementSection.ConfigurationElement, "Remove")
                .Where(new { settings = typeof(string) }).First();
            Command.CommandHelpers.HasAddedItemToList(elementSection, elementSection.ConfigurationElement, MethodRedo, MethodUndo, con, Command.TypeChange.Add);

            elementSection.AddItemFromCollection(key, 10, con);
        }


        public static void RemoveKeyValueCollection(IElementSection i, IElementSection parent)
        {

            MethodInfo MethodUndo = AccessPrivatePropertyHelper.GetMethod(parent.ConfigurationElement, "Add").First();
            MethodInfo MethodRedo = AccessPrivatePropertyHelper.GetMethod(parent.ConfigurationElement, "Remove")

                .Where(new { settings = typeof(string) }).First();
            Command.CommandHelpers.HasAddedItemToList(i, parent.ConfigurationElement, MethodRedo, MethodUndo, i.ConfigurationElement, Command.TypeChange.Remove);


            (parent.ConfigurationElement as KeyValueConfigurationCollection)
                .Remove((i.ConfigurationElement as KeyValueConfigurationElement).Key);
            (parent as ElementSection).Items.Remove(i);
        }


        public static void AddItemToSectionProviderSettings(ElementSection elementSection)
        {

            // calcule la clef par defaut
            string key = "newconn" + (elementSection.ConfigurationElement as ProviderSettingsCollection)
                .Count.ToString();

            // create
            var con = new ProviderSettings(key, string.Empty);

            (elementSection.ConfigurationElement as ProviderSettingsCollection).Add(con);


            MethodInfo MethodRedo = AccessPrivatePropertyHelper.GetMethod(elementSection.ConfigurationElement, "Add").First();
            MethodInfo MethodUndo = AccessPrivatePropertyHelper.GetMethod(elementSection.ConfigurationElement, "Remove")
                .Where(new { settings = typeof(string) }).First();

            MethodInfo MethodName = AccessPrivatePropertyHelper.GetMethod(con, "get_Name").First();

            Command.CommandHelpers.HasAddedItemToList(elementSection, elementSection.ConfigurationElement, MethodRedo, MethodUndo, MethodName, Command.TypeChange.Add);


            elementSection.AddItemFromCollection(key, 10, con);

        }

        public static void AddItemToSectionProviderSettingsWithChoose(ElementSection elementSection, Type type, MethodInfo method)
        {

            DirectoryInfo dir = new FileInfo(type.Module.FullyQualifiedName).Directory;

            if (!Datas.DirectoriesSearch.ContainsKeyFrom(dir))
                Datas.AddDirectoryLibrary(dir);

            Datas.LoadTypes(Datas.DirectoriesSearch);

            if (Datas.FileConfiguration == null)
                return;

            SelectAssembly frm = new SelectAssembly(
                Datas.DirectoriesSearch,
                new TypeContraint(type)
                );
           

            frm.ShowDialog();

            if (String.IsNullOrEmpty(frm.Retour))
                return;

            var con = Activator.CreateInstance(frm.TypeRetour);

            foreach (PropertyInfo item in frm.TypeRetour.GetProperties())
                if (item.PropertyType == typeof(string))
                    item.SetValue(con, "DefaultValue", null);

            method.Invoke(elementSection.ConfigurationElement, new object[] { con });


            MethodInfo MethodUndo = AccessPrivatePropertyHelper.GetMethod(elementSection.ConfigurationElement, "Remove")
                .Where(new { settings = typeof(KeyValueConfigurationElement) }).First();
            Command.CommandHelpers.HasAddedItemToList(elementSection, elementSection.ConfigurationElement, method, MethodUndo, con, Command.TypeChange.Add);


            Refresh(elementSection);
        }


        private static IElementSection Refresh(ElementSection elementSection)
        {

            
            if (elementSection.ConfigurationElement is IEnumerable)
            {

                IEnumerable ie = (elementSection.ConfigurationElement as IEnumerable);
                foreach (ConfigurationElement item in ie)
                    if (!elementSection.Contains(item))
                        return elementSection.AddConfigurationElement(item, item.GetType().Name);

            }

            return null;
        }


        public static void AddFromBoxCollection(ElementSection elementSection)
        {
            try
            {
                var i = AccessPrivatePropertyHelper.Invoke<ConfigurationElement>(elementSection.ConfigurationElement, "CreateNewElement", new { Name = "new" });

                MethodInfo MethodRedo = AccessPrivatePropertyHelper.GetMethod(elementSection.ConfigurationElement, "BaseAdd").Where(new { element = typeof(ConfigurationElement) }).First();
                MethodRedo.Invoke(elementSection.ConfigurationElement, new object[] { i });


                var newitem = Refresh(elementSection);


                List<MethodInfo> MethodUndo = AccessPrivatePropertyHelper.GetMethod(elementSection.ConfigurationElement, "Remove").Where(new { element = typeof(string) }).ToList();
                
                if (MethodUndo.Count == 0)
                    return;


                MethodInfo MethodReadName = AccessPrivatePropertyHelper.GetMethod(elementSection.ConfigurationElement, "GetElementKey").First();

                Command.CommandHelpers.HasAddedItemToList(newitem, elementSection.ConfigurationElement, MethodRedo, i, MethodUndo.First(), MethodReadName, Command.TypeChange.Add);

            }
            catch (Exception)
            {
                Debug.Print("Erreur -> " + elementSection.Path);
            }
            
        }

    }
}
